classdef TSprofileMatchEddyClass < handle
    %TSPROFILEMATCHEDDYCLASS 此类用于使海洋剖面与海洋涡旋的位置配准工作
    
    properties
        % 属性包括 剖面数据集TSprofile 涡旋数据集eddyArray
        % inedduType为类的固定属性，表示剖面匹配涡旋情况的各类枚举
        TSprofile
        eddyArray
        % ineddyArray
        ineddyType = ["OnlyInOneR","InTwoR","OnlyInTwoROutOneR","outTwoR","InThreeR","OnlyInThreeROutTwoR","outThreeR"];
    end
    
    methods
        function obj = TSprofileMatchEddyClass(TSprofile,eddyArray)
                    obj.TSprofile = TSprofile;
                    obj.eddyArray = eddyArray;
        end
        % % 利用剖面来匹配涡旋，找到每个涡旋含有的剖面(尚未有使用场景)
        % 
        % function eddyMatchprofile(obj)
        %     DisTance = 111000;
        %     for i = 1:length(obj.eddyArray)
        %         eddy = obj.eddyArray(i);
        %         t = [obj.TSprofile.profile.date];
        %         t_index = find([t <= eddy.time + 3 & t >= eddy.time - 3]);
        %         TS = TempSaltProfileClass.copy(obj.TSprofile,'index',t_index);
        %         ineddy(i).inOneR = 0;
        %         ineddy(i).inTwoR = 0;
        %         ineddy(i).inThreeR = 0;
        %         ineddy(i).deltaXY = [];
        %         ineddy(i).TSprofile = [];
        %         for j = 1:length(TS)
        %             lon = obj.TSprofile.lon(j);
        %             lat = obj.TSprofile.lat(j);
        %             DX = (lon - eddy.longitude) * DisTance/eddy.radius;
        %             DY = (lat - eddy.latitude) * DisTance/eddy.radius;
        %             % multiple_R = sqrt(DX^2 + DY^2);
        %             multiple_R = max([abs(DX) abs(DY)]);
        %             if multiple_R < 1
        %                 ineddy(i).inOneR = ineddy(i).inOneR + 1;
        %                 ineddy(i).deltaXY = [ineddy(i).deltaXY; DX DY];
        %                 ineddy(i).TSprofile = [ineddy(i).TSprofile, TempSaltProfileClass.copy(TS,'index',j)];
        %             elseif multiple_R < 2
        %                 ineddy(i).inTwoR = ineddy(i).inTwoR + 1;
        %                 ineddy(i).deltaXY = [ineddy(i).deltaXY; DX DY];
        %                 ineddy(i).TSprofile = [ineddy(i).TSprofile, TempSaltProfileClass.copy(TS,'index',j)];
        %             elseif multiple_R < 3
        %                 ineddy(i).inThreeR = ineddy(i).inThreeR + 1;
        %                 ineddy(i).deltaXY = [ineddy(i).deltaXY; DX DY];
        %                 ineddy(i).TSprofile = [ineddy(i).TSprofile, TempSaltProfileClass.copy(TS,'index',j)];
        %             end
        %         end
        %         obj.ineddyArray = ineddy;
        %     end
        % end


        % 利用eddy来匹配剖面，找到所有剖面的相对于涡旋的位置
        function profileMatchEddy(obj)
            R = 6371000;%地球半径
            DisTance = pi/180*R;
            for i = 1:length(obj.TSprofile.lon)
                i
                lon = obj.TSprofile.lon(i);
                lat = obj.TSprofile.lat(i);
                t = datetime(obj.TSprofile.profile(i).date.Year, obj.TSprofile.profile(i).date.Month, obj.TSprofile.profile(i).date.Day);
                eddys = obj.eddyArray([obj.eddyArray.time] == t);
                ineddy(i).inOneR = 0;
                ineddy(i).inTwoR = 0;
                ineddy(i).inThreeR = 0;
                ineddy(i).deltaXY = [];
                ineddy(i).type = [];
                for j = 1:length(eddys)

                    eddy = eddys(j);
                    DX = (lon - eddy.longitude) * DisTance/eddy.radius;
                    DY = (lat - eddy.latitude) * DisTance/eddy.radius;
                    % multiple_R = sqrt(DX^2 + DY^2);
                    multiple_R = max([abs(DX) abs(DY)]);
                    if multiple_R < 1
                        ineddy(i).inOneR = ineddy(i).inOneR + 1;
                        ineddy(i).deltaXY = [ineddy(i).deltaXY; DX DY];
                        ineddy(i).type = [ineddy(i).type eddy.type];
                    elseif multiple_R < 2
                        ineddy(i).inTwoR = ineddy(i).inTwoR + 1;
                        ineddy(i).deltaXY = [ineddy(i).deltaXY; DX DY];
                        ineddy(i).type = [ineddy(i).type eddy.type];
                    elseif multiple_R < 3
                        ineddy(i).inThreeR = ineddy(i).inThreeR + 1;
                        ineddy(i).deltaXY = [ineddy(i).deltaXY; DX DY];
                        ineddy(i).type = [ineddy(i).type eddy.type];
                    end
                end
            end
            % obj.ineddyArray = ineddy;
            obj.TSprofile.ineddyArray = ineddy;
        end
        
        %% 简易快速的涡旋与剖面匹配，仅仅只考虑最近涡旋
        function profileMatchEddy_simple(obj)
            R = 6371000;%地球半径
            DisTance = pi/180*R;
            for i = 1:length(obj.TSprofile.lon)
                i
                lon = obj.TSprofile.lon(i);
                lat = obj.TSprofile.lat(i);
                t = datetime(obj.TSprofile.profile(i).date.Year, obj.TSprofile.profile(i).date.Month, obj.TSprofile.profile(i).date.Day);
                eddys = obj.eddyArray([obj.eddyArray.time] == t);
                D = 9999;
                for j = 1:length(eddys)
                    eddy = eddys(j);
                    DX = (lon - eddy.longitude) * DisTance/eddy.radius;
                    DY = (lat - eddy.latitude) * DisTance/eddy.radius;
                    % multiple_R = sqrt(DX^2 + DY^2);
                    d = sqrt(DX^2 + DY^2);
                    if d < D
                        D = d;
                        ineddysimple(i).deltaXY = [DX DY];
                        ineddysimple(i).distance = d;
                        ineddysimple(i).type = eddy.type;
                    end
                    obj.TSprofile.ineddyArray = ineddysimple;
                end
            end

        end
        
        % 提取想要的DetectType  ineddyType = ["OnlyInOneR","InTwoR","OnlyInTwoROutOneR","outTwoR","InThreeR","OnlyInThreeROutTwoR","outThreeR"];

        function [DetectedTSprofile] = profileDetectBymultiR(obj, DetectType)
            
            detect_idx = [];
            ineddy = obj.TSprofile.ineddyArray;
            for i = 1:length(ineddy)
                [m, n] = size(ineddy(i).deltaXY);
                if strcmp(DetectType, obj.ineddyType(1)) 
                    if ineddy(i).inOneR ~= 0
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(2))
                    if ineddy(i).inOneR ~=0 || ineddy(i).inTwoR ~=0
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(3))
                    if ineddy(i).inOneR == 0 && ineddy(i).inTwoR ~=0
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(4))
                    if ineddy(i).inOneR == 0 && ineddy(i).inTwoR == 0 
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(5))
                    if ineddy(i).inOneR ~=0 || ineddy(i).inTwoR ~=0 || ineddy(i).inThreeR ~=0
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(6))
                    if ineddy(i).inOneR == 0 && ineddy(i).inTwoR == 0 && ineddy(i).inThreeR ~=0
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(7))
                    if m == 0
                        detect_idx = [detect_idx i];
                    end
                end
            end
            DetectedTSprofile = ArgoTempSaltProfileClass.copy(obj.TSprofile,'index', detect_idx);
            DetectedTSprofile.ineddydeltaXYDeal();
        end
        % 提取想要的DetectType  ineddyType = ["OnlyInOneR","InTwoR","OnlyInTwoROutOneR","outTwoR","InThreeR","OnlyInThreeROutTwoR","outThreeR"];
        %% 该函数考虑到了剖面重复出现在一倍半径 二倍半径的剖面的可能，较之上面具有更高的构建精度
        function [DetectedTSprofile] = profileDetectBymultiRByOnly(obj, DetectType)
            detect_idx = [];
            ineddy = obj.TSprofile.ineddyArray;
            for i = 1:length(ineddy)
                XY = ineddy(i).deltaXY;
                [m, ~] = size(XY);
                if strcmp(DetectType, obj.ineddyType(1)) %"OnlyInOneR"
                    if ineddy(i).inOneR == 1 && ineddy(i).inTwoR == 0
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(2))%"InTwoR"
                    if ineddy(i).inOneR + ineddy(i).inTwoR == 1
                        detect_idx = [detect_idx i];
                    end

                elseif strcmp(DetectType, obj.ineddyType(3))%"OnlyInTwoROutOneR"
                    if ineddy(i).inOneR == 0 && ineddy(i).inTwoR == 1
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(4))%"outTwoR"
                    if ineddy(i).inTwoR == 0 && ineddy(i).inOneR == 0
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(5))%"InThreeR"
                    if ineddy(i).inTwoR + ineddy(i).inOneR + ineddy(i).inThreeR == 1
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(6))%"OnlyInThreeROutTwoR"
                    if ineddy(i).inTwoR == 0 && ineddy(i).inOneR == 0 && ineddy(i).inThreeR == 1
                        detect_idx = [detect_idx i];
                    end
                elseif strcmp(DetectType, obj.ineddyType(7))%"outThreeR"
                    if ineddy(i).inTwoR + ineddy(i).inOneR + ineddy(i).inThreeR == 0
                        detect_idx = [detect_idx i];
                    end
                end
            end
            DetectedTSprofile = TempSaltProfileClass.copy(obj.TSprofile,'index', detect_idx);
            DetectedTSprofile.ineddydeltaXYDeal();
        end

    end
    methods(Static)
    end
end

